#include "serialmanager.h"
#include <QDebug>

SerialManager::SerialManager(QObject *parent)
    : QObject(parent)
    , m_serialPort(nullptr)
    , m_rxCount(0)
    , m_txCount(0)
    , m_autoSendTimer(nullptr)
    , m_lastError(QSerialPort::NoError)
    , m_lastErrorString("")
{
    // 创建串口对象
    m_serialPort = new QSerialPort(this);
    connect(m_serialPort, &QSerialPort::readyRead, this, &SerialManager::onReadyRead);
    connect(m_serialPort, &QSerialPort::errorOccurred, this, &SerialManager::onErrorOccurred);
    
    // 创建自动发送定时器
    m_autoSendTimer = new QTimer(this);
    connect(m_autoSendTimer, &QTimer::timeout, this, &SerialManager::onAutoSendTimeout);
}

SerialManager::~SerialManager()
{
    closePort();
}

bool SerialManager::openPort(const SerialConfig &config)
{
    // 如果已打开，先关闭
    if (m_serialPort->isOpen()) {
        closePort();
    }
    
    // 保存配置
    m_config = config;
    
    // 配置串口参数
    m_serialPort->setPortName(config.portName);
    m_serialPort->setBaudRate(config.baudRate);
    m_serialPort->setDataBits(config.dataBits);
    m_serialPort->setStopBits(config.stopBits);
    m_serialPort->setParity(config.parity);
    m_serialPort->setFlowControl(config.flowControl);
    
    // 尝试打开串口
    if (m_serialPort->open(QIODevice::ReadWrite)) {
        qDebug() << "[SerialManager] 串口打开成功:" << config.portName;
        emit portOpened();
        return true;
    } else {
        QString error = m_serialPort->errorString();
        qDebug() << "[SerialManager] 串口打开失败:" << error;
        emit errorOccurred(error);
        return false;
    }
}

void SerialManager::closePort()
{
    if (m_serialPort->isOpen()) {
        // 停止自动发送
        stopAutoSend();
        
        // 关闭串口
        m_serialPort->close();
        qDebug() << "[SerialManager] 串口已关闭";
        emit portClosed();
    }
}

bool SerialManager::isOpen() const
{
    return m_serialPort && m_serialPort->isOpen();
}

QList<QSerialPortInfo> SerialManager::getAvailablePorts() const
{
    return QSerialPortInfo::availablePorts();
}

qint64 SerialManager::sendData(const QByteArray &data)
{
    if (!isOpen()) {
        qDebug() << "[SerialManager] 串口未打开，无法发送数据";
        return -1;
    }
    
    if (data.isEmpty()) {
        return 0;
    }
    
    qint64 bytesWritten = m_serialPort->write(data);
    if (bytesWritten > 0) {
        m_txCount += bytesWritten;
        emit statisticsUpdated(m_rxCount, m_txCount);
        qDebug() << "[SerialManager] 发送数据:" << bytesWritten << "字节";
    } else {
        qDebug() << "[SerialManager] 发送失败";
    }
    
    return bytesWritten;
}

qint64 SerialManager::sendText(const QString &text, bool addNewline)
{
    QByteArray data = text.toUtf8();
    if (addNewline) {
        data.append("\r\n");
    }
    return sendData(data);
}

qint64 SerialManager::sendHex(const QString &hexString)
{
    bool ok;
    QByteArray data = hexToByteArray(hexString, &ok);
    if (!ok) {
        qDebug() << "[SerialManager] 十六进制格式错误";
        emit errorOccurred("十六进制格式错误");
        return -1;
    }
    return sendData(data);
}

void SerialManager::startAutoSend(const QByteArray &data, int interval)
{
    m_autoSendData = data;
    m_autoSendTimer->start(interval);
    qDebug() << "[SerialManager] 启动自动发送，间隔:" << interval << "ms";
}

void SerialManager::stopAutoSend()
{
    if (m_autoSendTimer->isActive()) {
        m_autoSendTimer->stop();
        qDebug() << "[SerialManager] 停止自动发送";
    }
}

bool SerialManager::isAutoSending() const
{
    return m_autoSendTimer->isActive();
}

void SerialManager::clearStatistics()
{
    m_rxCount = 0;
    m_txCount = 0;
    emit statisticsUpdated(m_rxCount, m_txCount);
    qDebug() << "[SerialManager] 统计信息已清空";
}

QByteArray SerialManager::byteArrayToHex(const QByteArray &data)
{
    QString hexString;
    for (int i = 0; i < data.size(); ++i) {
        hexString += QString("%1 ").arg((unsigned char)data[i], 2, 16, QChar('0')).toUpper();
    }
    return hexString.trimmed().toUtf8();
}

QByteArray SerialManager::hexToByteArray(const QString &hexString, bool *ok)
{
    if (ok) *ok = true;
    
    QByteArray result;
    QString cleaned = hexString;
    
    // 移除所有空格和常见分隔符
    cleaned.remove(' ');
    cleaned.remove(',');
    cleaned.remove("0x");
    cleaned.remove("0X");
    cleaned = cleaned.trimmed();
    
    // 检查是否为有效的十六进制字符
    for (QChar ch : cleaned) {
        if (!ch.isDigit() && !(ch >= 'A' && ch <= 'F') && !(ch >= 'a' && ch <= 'f')) {
            if (ok) *ok = false;
            return QByteArray();
        }
    }
    
    // 确保长度为偶数
    if (cleaned.length() % 2 != 0) {
        if (ok) *ok = false;
        return QByteArray();
    }
    
    // 转换为字节数组
    for (int i = 0; i < cleaned.length(); i += 2) {
        QString byteStr = cleaned.mid(i, 2);
        bool convertOk;
        unsigned char byte = byteStr.toUInt(&convertOk, 16);
        if (convertOk) {
            result.append(byte);
        } else {
            if (ok) *ok = false;
            return QByteArray();
        }
    }
    
    return result;
}

QString SerialManager::getErrorString() const
{
    return m_serialPort ? m_serialPort->errorString() : QString();
}

void SerialManager::onReadyRead()
{
    QByteArray data = m_serialPort->readAll();
    if (!data.isEmpty()) {
        m_rxCount += data.size();
        emit statisticsUpdated(m_rxCount, m_txCount);
        emit dataReceived(data);
        qDebug() << "[SerialManager] 接收数据:" << data.size() << "字节";
    }
}

void SerialManager::onAutoSendTimeout()
{
    if (!m_autoSendData.isEmpty()) {
        sendData(m_autoSendData);
    }
}

void SerialManager::onErrorOccurred(QSerialPort::SerialPortError error)
{
    // 忽略NoError和资源错误（关闭时会触发）
    if (error == QSerialPort::NoError || error == QSerialPort::ResourceError) {
        return;
    }
    
    // 获取错误信息
    QString errorString = m_serialPort->errorString();
    
    // 错误去重：避免相同错误重复触发
    if (error == m_lastError && errorString == m_lastErrorString) {
        return;
    }
    
    m_lastError = error;
    m_lastErrorString = errorString;
    
    qDebug() << "[SerialManager] 串口错误:" << errorString << "错误代码:" << error;
    
    // 严重错误：自动关闭串口
    if (error == QSerialPort::PermissionError ||
        error == QSerialPort::DeviceNotFoundError ||
        error == QSerialPort::OpenError ||
        error == QSerialPort::NotOpenError ||
        error == QSerialPort::WriteError ||
        error == QSerialPort::ReadError) {
        
        qDebug() << "[SerialManager] 检测到严重错误，自动关闭串口";
        closePort();
    }
    
    // 发送错误信号（UI层应该谨慎处理，避免弹窗）
    emit errorOccurred(errorString);
}

